/*
 * Dijjer - A Peer to Peer HTTP Cache
 * Copyright (C) 2004,2005 Change.Tv, Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package dijjer.io.comm;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import dijjer.util.logging.Logger;

public class MessageType {

    public static final String VERSION = "$Id: MessageType.java 33 2009-03-20 13:26:16Z mathias.demare $";

	private static HashMap _specs = new HashMap();

	private final String _name;
	private final LinkedList _orderedFields = new LinkedList();
	private final HashMap _fields = new HashMap();
	private final HashMap _linkedListTypes = new HashMap();

	static {
		DMT.init();
	}

	public MessageType(String name) {
		_name = name;
		Integer id = new Integer(name.hashCode());
		if (_specs.containsKey(id)) {
			throw new RuntimeException("A message type by the name of " + name + " already exists!");
		}
		_specs.put(id, this);
	}

	public void unregister() {
		_specs.remove(new Integer(_name.hashCode()));
	}
	
	public void addLinkedListField(String name, Class parameter) {
		_linkedListTypes.put(name, parameter);
		addField(name, LinkedList.class);
	}

	public void addField(String name, Class type) {
		_fields.put(name, type);
		_orderedFields.addLast(name);
	}

	public boolean checkType(String fieldName, Object fieldValue) {
		if (fieldValue == null) {
			return false;
		}
		if(_fields.get(fieldName).equals(AbstractPeer.class)) {
			if(_fields.get(fieldName).equals(fieldValue.getClass().getSuperclass()))
				return true;
		}
		return _fields.get(fieldName).equals(fieldValue.getClass());
	}

	public Class typeOf(String field) {
		return (Class) _fields.get(new Integer(field.hashCode()));
	}

	public boolean equals(Object o) {
		if (!(o instanceof MessageType)) {
			return false;
		}
		return ((MessageType) o)._name.equals(_name);
	}

	public static MessageType getSpec(Integer specID) {
		if (!_specs.containsKey(specID)) {
			Logger.warning("Unrecognised message type received (" + specID + ")");
			return null;
		}
		return (MessageType) _specs.get(specID);
	}

	public String getName() {
		return _name;
	}

	public Map getFields() {
		return _fields;
	}

	public LinkedList getOrderedFields() {
		return _orderedFields;
	}
	
	public Map getLinkedListTypes() {
		return _linkedListTypes;
	}
}